/*
*  Copyright (C) 2009  Peter Kist & Jan Ripke
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __galaxy_app_context_h
#define __galaxy_app_context_h 1

#if _WIN32
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif

#include <functional>
#include <set>
#include <string>

#include <boost/serialization/nvp.hpp>
#include <boost/unordered_map.hpp>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;


namespace galaxy {

    class Galaxy;

    /** Path definition (xml init file component). This class is used to read (and possibly write)
    * path information from the <application>.ini file
    */
    class AppPathDefinition {

        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version) {
            ar & BOOST_SERIALIZATION_NVP(m_Name) & BOOST_SERIALIZATION_NVP(m_Path);
        }

    public:

        std::string m_Name;     /**< logical name of path */
        std::string m_Path;     /**< physical location of path */

        AppPathDefinition () { };
        AppPathDefinition (std::string name, fs::path path) : m_Name(name), m_Path (path.string()) { };

        fs::path path() { return fs::path (m_Path); };
    };

    /** Manages the directories that are used by the game. The \b bin directory is derived from the
    * executable, whereas the other directories are loaded from application.ini
    */
    struct AppPath {
        AppPath ();
        ~AppPath () { };

        fs::path m_AppName;

        fs::path bin;
        fs::path config;            /**< directory where configuration file are located */
        fs::path keymaps;           /**< directory where the keymaps are located */
        fs::path logs;              /**< directory where log files are located */
        fs::path plugins;           /**< directory where plugins are located */

        /** load the ini file for the main application. The file name of the ini file is <main-application>.ini */
        bool loadIniFile ();
        bool saveIniFile ();
        bool validatePaths ();

    private:
        fs::path normalizePath (std::string p);
    };


    class AppContext
    {
        /** singleton application context that is used through-out the game */
        static AppContext * appContext;


    public:

#if _WIN32
        HINSTANCE         hInstance;        /**< window handle from WinMain() */
        INT               nCmdShow;         /**< argument from WinMain() */
#endif
        Galaxy          * game;             /**< game object */
        AppPath           paths;            /**< paths that are used by the game (dynamically loaded) */

    public:
        AppContext(void);
        ~AppContext(void) {};

        static AppContext& singleton() { return *appContext; };
    };

} // namespace galaxy

#endif // __galaxy_app_context_h
